package com.xbongbong.saas.toolbox.help;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author zcp
 * @version v1.0
 * @date 2019/3/13 10:23
 * @since v1.0
 */
public class SortHelp {
    public static final String KEY_STRING = "String";
    public static final String KEY_LONG = "Long";
    public static final String KEY_INTEGER = "Integer";
    /**
     * 排行top10
     */
    public static final int TOP_10 = 10;

    /**
     * 调用方法，如：Map<Long, Integer> corpRankDepMap = (Map<Long, Integer>) TargetHelp.sortMapValueDouble(amountDepMap, "Long");
     *
     * @param object 要排序的map
     * @param keyType map内key值的类型
     * 				keyType = "String"  	object为Map<String, Double> map   员工--金额
     * 				keyType = "Long"  		object为Map<Long, Double> map  部门--金额（pro这边主键都变为了Long类型）
     * 				keyType = "Integer"		object为Map<Integer, Double> map  比如，productId--金额
     * @return
     * @throws
     *
     * @author hongxiao
     * @date: 2019-02-21 10:39
     * @since v1.0
     * @version v1.0
     */
    public static Object sortMapValueDouble(Object object, String keyType) {
        //top传null，获取全部
        return sortMapValueDouble(object, keyType, null);
    }
    /**
     * 为map型内value值排序，降序； 然后把排好序的排名置入新的Map（key---rank值）
     * 其中key为Long、String、Integer类型，value为Double类型
     * @param object 要排序的map，key值的类型与keyType保持一致
     * @param keyType map内key值的类型
     * @param top 只获取前top名，top为null时不限制
     * @return java.lang.Object
     * @author zcp
     * @date 2019/3/13 10:37
     * @since v1.0
     * @version v1.0
     */
    public static Object sortMapValueDouble(Object object, String keyType, Integer top) {
                Object resultObject = null;
                if (KEY_STRING.equals(keyType)) {
            Map<String, Double> map = (Map<String, Double>) object;
            resultObject = sortMapValueDouble4KeyString(map, top);
        } else if (KEY_LONG.equals(keyType)) {
            Map<Long, Double> map = (Map<Long, Double>) object;
            resultObject = sortMapValueDouble4KeyLong(map, top);
        } else if (KEY_INTEGER.equals(keyType)) {
            Map<Integer, Double> map = (Map<Integer, Double>) object;
            resultObject = sortMapValueDouble4KeyInteger(map, top);
        }
        return resultObject;
    }

    /**
     * 为map型内value值排序
     * 其中key为Long类型，value为Double类型
     *
     * @param map 待排序map
     * @param top 只获取前top名，top为null时不限制
     * @return java.util.Map<java.lang.Long,java.lang.Integer> 已经排过顺序的map，为LinkedHashMap类型
     * @author zcp
     * @date 2019/2/28 22:28
     * @since v1.0
     * @version v1.0
     */
    public static Map<Long, Integer> sortMapValueDouble4KeyLong(Map<Long, Double> map, Integer top) {
        Map<Long, Integer> corpRankMap = new LinkedHashMap<>();
        if (map.size() == 0) {
            return corpRankMap;
        }
        //用于存放上一个的数量，处理两个部门(或员工)的数量一致，则让其排名也一样
        Double preAmount = null;
        //用于存放上一个的排名
        Integer preRank = 0;
        List<Map.Entry<Long, Double>> mapList = new ArrayList<>(map.entrySet());
        Collections.sort(mapList, new Comparator<Map.Entry<Long, Double>>(){
            @Override
            public int compare(Map.Entry<Long, Double> o1,
                               Map.Entry<Long, Double> o2) {
                //降序
                return o2.getValue().compareTo(o1.getValue());
            }
        });
        //mapList的value已排序--从大到小
        for (int i = 0; i < mapList.size(); i++) {
            if (top != null && Objects.equals(i, top)) {
                //只获取前top名
                break;
            }
            Integer rank = i + 1;
            Map.Entry<Long, Double> entry = mapList.get(i);
            Long key = entry.getKey();
            Double value = entry.getValue();
            //该key对应数量与上一个key对应数量一致
            if (preAmount != null && value.equals(preAmount)) {
                //排名也置为与上一个一致
                rank = preRank;
            } else {
                //第一次或者数量不一致的
                preAmount = value;
                preRank = rank;
            }
            corpRankMap.put(key, rank);
        }
        return corpRankMap;
    }
    /**
     * 为map型内value值排序
     * 其中key为String类型，value为Double类型
     *
     * @param map 待排序map
     * @param top 只获取前top名，top为null时不限制
     * @return java.util.Map<java.lang.Long,java.lang.Integer> 已经排过顺序的map，为LinkedHashMap类型
     * @author zcp
     * @date 2019/3/13 10:32
     * @since v1.0
     * @version v1.0
     */
    public static Map<String, Integer> sortMapValueDouble4KeyString(Map<String, Double> map, Integer top) {
        Map<String, Integer> corpRankMap = new LinkedHashMap<>();
        if (map.size() == 0) {
            return corpRankMap;
        }
        //用于存放上一个的数量，处理两个部门(或员工)的数量一致，则让其排名也一样
        Double preAmount = null;
        //用于存放上一个的排名
        Integer preRank = 0;
        List<Map.Entry<String, Double>> mapList = new ArrayList<>(map.entrySet());
        Collections.sort(mapList, new Comparator<Map.Entry<String, Double>>(){
            @Override
            public int compare(Map.Entry<String, Double> o1,
                               Map.Entry<String, Double> o2) {
                //降序
                return o2.getValue().compareTo(o1.getValue());
            }
        });
        //mapList的value已排序--从大到小
        for (int i = 0; i < mapList.size(); i++) {
            if (top != null && Objects.equals(i, top)) {
                //只获取前top名
                break;
            }
            Integer rank = i + 1;
            Map.Entry<String, Double> entry = mapList.get(i);
            String key = entry.getKey();
            Double value = entry.getValue();
            //该key对应数量与上一个key对应数量一致
            if (preAmount != null && value.equals(preAmount)) {
                //排名也置为与上一个一致
                rank = preRank;
            } else {
                //第一次或者数量不一致的
                preAmount = value;
                preRank = rank;
            }
            corpRankMap.put(key, rank);
        }
        return corpRankMap;
    }
    /**
     * 为map型内value值排序
     * 其中key为Integer类型，value为Double类型
     *
     * @param map 待排序map
     * @param top 只获取前top名，top为null时不限制
     * @return java.util.Map<java.lang.Long,java.lang.Integer> 已经排过顺序的map，为LinkedHashMap类型
     * @author zcp
     * @date 2019/3/13 10:32
     * @since v1.0
     * @version v1.0
     */
    public static Map<Integer, Integer> sortMapValueDouble4KeyInteger(Map<Integer, Double> map, Integer top) {
        Map<Integer, Integer> corpRankMap = new LinkedHashMap<>();
        if (map.size() == 0) {
            return corpRankMap;
        }
        //用于存放上一个的数量，处理两个部门(或员工)的数量一致，则让其排名也一样
        Double preAmount = null;
        //用于存放上一个的排名
        Integer preRank = 0;
        List<Map.Entry<Integer, Double>> mapList = new ArrayList<>(map.entrySet());
        Collections.sort(mapList, new Comparator<Map.Entry<Integer, Double>>(){
            @Override
            public int compare(Map.Entry<Integer, Double> o1,
                               Map.Entry<Integer, Double> o2) {
                //降序
                return o2.getValue().compareTo(o1.getValue());
            }
        });
        //mapList的value已排序--从大到小
        for (int i = 0; i < mapList.size(); i++) {
            if (top != null && Objects.equals(i, top)) {
                //只获取前top名
                break;
            }
            Integer rank = i + 1;
            Map.Entry<Integer, Double> entry = mapList.get(i);
            Integer key = entry.getKey();
            Double value = entry.getValue();
            //该key对应数量与上一个key对应数量一致
            if (preAmount != null && value.equals(preAmount)) {
                //排名也置为与上一个一致
                rank = preRank;
            } else {
                //第一次或者数量不一致的
                preAmount = value;
                preRank = rank;
            }
            corpRankMap.put(key, rank);
        }
        return corpRankMap;
    }

    /**
     * 为map型内value值排序，降序； 然后把排好序的排名置入新的Map（key---rank值），默认获取所有排序
     * 其中key为Long、String、Integer类型，value为Integer类型
     *
     * @param object 要排序的map
     * @param keyType map内key值的类型
     * 				keyType = "String"  	object为Map<String, Integer> map   员工--数量
     * 				keyType = "Long"  		object为Map<Long, Integer> map  部门--数量（pro这边主键都变为了Long类型）
     * 				keyType = "Integer"		object为Map<Integer, Integer> map  比如，productId--数量
     *
     * @return java.lang.Object
     * @author zcp
     * @date 2019/3/15 22:22
     * @since v1.0
     * @version v1.0
     */
    public static Object sortMapValueInteger(Object object, String keyType) {
        //top传null，获取全部
        return sortMapValueInteger(object, keyType, null);
    }
    /**
     * 为map型内value值排序，降序； 然后把排好序的排名置入新的Map（key---rank值）
     * 其中key为Long、String、Integer类型，value为Integer类型
     * @param object 要排序的map，key值的类型与keyType保持一致
     * @param keyType map内key值的类型
     * @param top 只获取前top名，top为null时不限制
     * @author zcp
     * @date 2019/3/15 22:16
     * @since v1.0
     * @version v1.0
     */
    public static Object sortMapValueInteger(Object object, String keyType, Integer top) {
        Object resultObject = null;
        if (KEY_STRING.equals(keyType)) {
            Map<String, Integer> map = (Map<String, Integer>) object;
            resultObject = sortMapValueInteger4KeyString(map, top);
        } else if (KEY_LONG.equals(keyType)) {
            Map<Long, Integer> map = (Map<Long, Integer>) object;
            resultObject = sortMapValueInteger4KeyLong(map, top);
        }
        return resultObject;
    }

    /**
     * 为map型内value值排序
     * 其中key为Long类型，value为Integer类型
     *
     * @param map 待排序map
     * @param top 只获取前top名，top为null时不限制
     * @return java.util.Map<java.lang.Long,java.lang.Integer> 已经排过顺序的map，为LinkedHashMap类型
     * @author zcp
     * @date 2019/3/15 22:18
     * @since v1.0
     * @version v1.0
     */
    public static Map<Long, Integer> sortMapValueInteger4KeyLong(Map<Long, Integer> map, Integer top) {
        Map<Long, Integer> corpRankMap = new LinkedHashMap<>();
        if (map.size() == 0) {
            return corpRankMap;
        }
        //用于存放上一个的数量，处理两个部门(或员工)的数量一致，则让其排名也一样
        Integer preValue = null;
        //用于存放上一个的排名
        Integer preRank = 0;
        List<Map.Entry<Long, Integer>> mapList = new ArrayList<>(map.entrySet());
        Collections.sort(mapList, new Comparator<Map.Entry<Long, Integer>>(){
            @Override
            public int compare(Map.Entry<Long, Integer> o1,
                               Map.Entry<Long, Integer> o2) {
                //降序
                return o2.getValue().compareTo(o1.getValue());
            }
        });
        //mapList的value已排序--从大到小
        for (int i = 0; i < mapList.size(); i++) {
            if (top != null && Objects.equals(i, top)) {
                //只获取前top名
                break;
            }
            Integer rank = i + 1;
            Map.Entry<Long, Integer> entry = mapList.get(i);
            Long key = entry.getKey();
            Integer value = entry.getValue();
            //该key对应数量与上一个key对应数量一致
            if (preValue != null && value.equals(preValue)) {
                //排名也置为与上一个一致
                rank = preRank;
            } else {
                //第一次或者数量不一致的
                preValue = value;
                preRank = rank;
            }
            corpRankMap.put(key, rank);
        }
        return corpRankMap;
    }
    /**
     * 为map型内value值排序
     * 其中key为String类型，value为Integer类型
     *
     * @param map 待排序map
     * @param top 只获取前top名，top为null时不限制
     * @return java.util.Map<java.lang.Long,java.lang.Integer> 已经排过顺序的map，为LinkedHashMap类型
     * @author zcp
     * @date 2019/3/13 10:32
     * @since v1.0
     * @version v1.0
     */
    public static Map<String, Integer> sortMapValueInteger4KeyString(Map<String, Integer> map, Integer top) {
        Map<String, Integer> corpRankMap = new LinkedHashMap<>();
        if (map.size() == 0) {
            return corpRankMap;
        }
        //用于存放上一个的数量，处理两个部门(或员工)的数量一致，则让其排名也一样
        Integer preValue = null;
        //用于存放上一个的排名
        Integer preRank = 0;
        List<Map.Entry<String, Integer>> mapList = new ArrayList<>(map.entrySet());
        Collections.sort(mapList, new Comparator<Map.Entry<String, Integer>>(){
            @Override
            public int compare(Map.Entry<String, Integer> o1,
                               Map.Entry<String, Integer> o2) {
                //降序
                return o2.getValue().compareTo(o1.getValue());
            }
        });
        //mapList的value已排序--从大到小
        for (int i = 0; i < mapList.size(); i++) {
            if (top != null && Objects.equals(i, top)) {
                //只获取前top名
                break;
            }
            Integer rank = i + 1;
            Map.Entry<String, Integer> entry = mapList.get(i);
            String key = entry.getKey();
            Integer value = entry.getValue();
            //该key对应数量与上一个key对应数量一致
            if (preValue != null && value.equals(preValue)) {
                //排名也置为与上一个一致
                rank = preRank;
            } else {
                //第一次或者数量不一致的
                preValue = value;
                preRank = rank;
            }
            corpRankMap.put(key, rank);
        }
        return corpRankMap;
    }
}
